<template>
  <el-drawer
    v-model="drawerVisible"
    size="50%"
    :close-on-click-modal="false"
    :before-close="handleClose"
    :show-close="false"
    destroy-on-close
  >
    <template #header>
      <div class="flex items-center justify-between w-full">
        <div class="flex items-center">
          <el-button
            link
            @click="handleClose"
            class="mr-2"
          >
            <el-icon><Close /></el-icon>
          </el-button>
          <span class="text-lg font-medium">
            {{ dialogType === 'add' ? 'Add Organization Type' : 'Modify Organization Type' }}
          </span>
        </div>
        <div class="flex gap-2">
          <el-button @click="handleClose">Cancel</el-button>
          <el-button type="primary" @click="submitForm">Submit</el-button>
        </div>
      </div>
    </template>

    <div class="drawer-content p-6">
      <el-form
        ref="formRef"
        :model="form"
        :rules="rules"
        label-width="180px"
        label-position="left"
      >
        <el-form-item
          label="Organization Type:"
          prop="type"
          v-if="dialogType === 'add'"
        >
          <el-input
            v-model="form.type"
            placeholder="Please enter"
            :maxlength="100"
            :show-word-limit="true"
          />
        </el-form-item>

        <el-form-item label="Authority Type:" prop="authorityType">
          <div class="flex gap-4">
            <el-checkbox-group v-model="form.authorityType">
              <el-checkbox :value="'Web'">Web</el-checkbox>
              <el-checkbox :value="'App'">App</el-checkbox>
            </el-checkbox-group>
          </div>
        </el-form-item>

        <!-- Web Permissions Section -->
        <template v-if="form.authorityType.includes('Web')">
          <el-form-item
            label="Web Permissions:"
            prop="webPermissions"
            class="w-full"
          >
            <div class="permissions-search mb-4 w-full">
              <el-input
                v-model="permissionSearch"
                placeholder="Please enter"
                :prefix-icon="Search"
                clearable
                class="w-full"
              />
            </div>
          </el-form-item>

          <div class="permissions-container w-full">
            <div class="select-all-bar">
              <el-checkbox v-model="selectAll" @change="handleSelectAll">Select All</el-checkbox>
            </div>
            <div class="permission-tree-wrapper">
              <el-tree
                ref="permissionTree"
                :data="menuTreeData"
                :props="treeProps"
                show-checkbox
                node-key="id"
                :filter-node-method="filterNode"
                class="w-full permission-tree"
                @check="onTreeCheck"
              />
            </div>
          </div>
        </template>
      </el-form>
    </div>
  </el-drawer>
</template>

<script lang="ts" setup>
import { ref, reactive, watch, nextTick, onMounted } from "vue";
import type { FormInstance, FormRules } from "element-plus";
import { Search, Close } from "@element-plus/icons-vue";
import { roleApi, organizationTypeApi } from "@/api/authority";
import { filterMenus } from "@/utils/menuFilter";
import { logger } from "@/utils/logger";

const props = defineProps({
  visible: {
    type: Boolean,
    default: false
  },
  formData: {
    type: Object,
    default: () => ({})
  },
  dialogType: {
    type: String,
    default: "add" // 'add' or 'edit'
  }
});

const emit = defineEmits(["update:visible", "submit-success"]);

// 表单实例与抽屉显隐
const formRef = ref<FormInstance>();
const drawerVisible = ref(props.visible);
const permissionSearch = ref("");
const selectAll = ref(false);
const permissionTree = ref<any>(null);

// 表单数据
const form = reactive({
  id: "",                        
  type: "",
  authorityType: [] as string[],  // Web/App 文本数组
  menuIdList: [] as (string | number)[]
});

// 动态菜单树（与角色管理一致）
const menuTreeData = ref<any[]>([]);
// 增加 disabled 字段映射，便于“全选置灰”
const treeProps = { children: "children", label: "name", disabled: "disabled" } as const;

// 权限树过滤：按 name 匹配
const filterNode = (value: string, data: any) => {
  if (!value) return true;
  return String(data.name || data.label || "").toLowerCase().includes(value.toLowerCase());
};

// 监听搜索关键字，实时过滤树
watch(permissionSearch, (val) => {
  permissionTree.value?.filter(val);
});

// 加载菜单树：统一 id 为字符串，children 为空时补空数组，避免 setCheckedKeys 不生效
const loadMenuTree = async () => {
  try {
    const res = await roleApi.getAddQuery();
    const raw = Array.isArray(res.data) ? res.data : [];
    
    // 应用菜单过滤
    const filteredRaw = filterMenus(raw);
    
    const normalize = (nodes: any[]) => {
      const walk = (arr: any[]) => (arr || []).forEach(n => {
        n.id = String(n.id);
        if (!Array.isArray(n.children)) n.children = [];
        if (n.children.length) walk(n.children);
      });
      walk(nodes);
      return nodes;
    };
    menuTreeData.value = normalize(filteredRaw);
  } catch (e) {
    logger.error('加载菜单树失败', e);
    menuTreeData.value = [];
  }
};

// 根据组织类型ID加载权限并勾选
const loadTypePermissions = async (id: string) => {
  try {
    const res = await organizationTypeApi.getTypePermissions(id);
    const auth: string = res?.data?.authorityType || '';
    const menus: any[] = res?.data?.menuIdList || [];

    // authorityType 使用文本并不可编辑
    const arr = String(auth)
      .split(',')
      .map((s: string) => s.trim())
      .filter(Boolean)
      .map((v: string) => (v === '0' ? 'Web' : v === '1' ? 'App' : v));
    form.authorityType = Array.from(new Set(arr));

    nextTick(() => {
      // 只设置有效的叶子节点为选中状态
      const allLeafIds = getLeafIds(menuTreeData.value);
      const validMenuIds = menus
        .map((x: any) => String(x))
        .filter((id: string) => allLeafIds.includes(id));
      
      permissionTree.value?.setCheckedKeys(validMenuIds);
      updateMenuIdListFromTree();
    });
  } catch (e) {
    logger.error('加载组织类型权限失败', e);
  }
};

// 表单校验规则
const rules = reactive<FormRules>({
  type: [
    {
      required: true,
      message: "Please enter organization type",
      trigger: "blur"
    },
    {
      max: 100,
      message: "Organization type cannot exceed 100 characters",
      trigger: "blur"
    }
  ],
  authorityType: [
    {
      required: true,
      validator: (rule: any, value: any, callback: any) => {
        if (!value || value.length === 0) {
          callback(new Error('Please select at least one authority type'));
        } else {
          callback();
        }
      },
      trigger: "change"
    }
  ],
  // Web Permissions 不做必填或选择校验，保持样式但允许为空
});

// 监听可见性：父传入 visible 改变时同步抽屉显隐
watch(
  () => props.visible,
  val => {
    drawerVisible.value = val;
  }
);

// 监听抽屉可见性：同步回父组件
watch(
  () => drawerVisible.value,
  val => {
    emit("update:visible", val);
  }
);

// 监听父组件回填数据：进入编辑态时拉取权限并勾选
watch(
  () => props.formData,
  val => {
    if (Object.keys(val).length > 0) {
      // Reset form
      resetForm();
      // Set form data
      // 使用后端返回的 id 作为唯一标识（与接口文档一致）
      form.id = String((val as any).id ?? "");
      form.type = (val as any).type || (val as any).organizationName || "";
      // 加载菜单树与当前权限
      loadMenuTree().then(() => {
        if (form.id) {
          loadTypePermissions(String(form.id));
        }
      });
    }
  },
  { immediate: true, deep: true }
);
// 叶子节点工具
const getLeafIds = (nodes: any[]): any[] => {
  const ids: any[] = [];
  const walk = (arr: any[]) => arr.forEach(n => {
    if (n.children && n.children.length) walk(n.children); else ids.push(String(n.id));
  });
  walk(nodes || []);
  return ids;
};

// 树勾选变化：只保存叶子节点，更新全选
const onTreeCheck = () => {
  updateMenuIdListFromTree();
};

const updateMenuIdListFromTree = () => {
  // 只保存勾选的叶子节点
  const checkedKeys = (permissionTree.value?.getCheckedKeys() || []).map((x: any) => String(x));
  const allLeafIds = getLeafIds(menuTreeData.value);
  const checkedLeafIds = checkedKeys.filter((id: string) => allLeafIds.includes(id));
  
  form.menuIdList = checkedLeafIds;
  
  // 全选状态基于叶子节点判断
  selectAll.value = allLeafIds.length > 0 && checkedLeafIds.length === allLeafIds.length;
};

// 全选/全不选（只操作叶子节点）
const handleSelectAll = (val: boolean) => {
  if (!permissionTree.value) return;
  if (val) {
    // 只设置所有叶子节点为选中
    const allLeafIds = getLeafIds(menuTreeData.value);
    permissionTree.value.setCheckedKeys(allLeafIds);
  } else {
    permissionTree.value.setCheckedKeys([]);
  }
  updateMenuIdListFromTree();
};

// 提交表单：转换 authorityType 为编码并提交
const submitForm = async () => {
  if (!formRef.value) return;

  await formRef.value.validate((valid, fields) => {
    if (valid) {
      logger.dev('表单验证通过，准备提交数据'); // 调试日志
      
      // 构建提交数据（authorityType 按后端要求传 '0'/'1' 编码；menuIdList 传字符串数组）
      const toAuthorityCode = (arr: string[] | string): string => {
        const list: string[] = Array.isArray(arr)
          ? arr
          : String(arr || '')
              .split(',')
              .map((s: string) => s.trim())
              .filter(Boolean);
        const codes = list.map((v: string) => (v === 'Web' ? '0' : v === 'App' ? '1' : String(v)));
        return Array.from(new Set(codes)).sort().join(',');
      };

      const submitData = {
        id: form.id,
        authorityType: toAuthorityCode(form.authorityType),
        // 只提交选中的叶子节点
        menuIdList: (form.menuIdList || []).map((x: any) => String(x))
      };

      logger.dev('提交数据:', submitData); // 调试日志

      // 直接调用API
      import('../data').then(async ({ updateOrganizationTypePermissions }) => {
        try {
          const result = await updateOrganizationTypePermissions(submitData);
          logger.dev('API响应:', result); // 调试日志
          emit("submit-success", result);
        } catch (error) {
          logger.error('API调用失败:', error);
          emit("submit-success", { success: false, message: '操作失败' });
        }
      });
    } else {
      logger.warn('表单验证失败:', fields);
    }
  });
};

// Handle drawer close
const handleClose = () => {
  drawerVisible.value = false;
};

// 重置表单
const resetForm = () => {
  form.id = "";
  form.type = "";
  form.authorityType = [];
  form.menuIdList = [];

  // 重置树
  selectAll.value = false;
  permissionTree.value?.setCheckedKeys([]);
};

onMounted(async () => {
  await loadMenuTree();
});
</script>

<style lang="scss" scoped>
.drawer-content {
  height: 100%;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
}

.permissions-container {
  border: 1px solid #e4e7ed;
  border-radius: 6px;
  overflow: hidden;
  background-color: #fff;
  margin-top: 16px;
}

.select-all-bar {
  background-color: #f5f7fa;
  padding: 10px 12px;
  border-bottom: 1px solid #e4e7ed;
  position: sticky;
  top: 0;
  z-index: 1;
}

.permission-tree-wrapper {
  max-height: 400px;
  overflow-y: auto;
  padding: 8px 12px;
}



:deep(.el-tree-node__content) { height: 30px; }

:deep(.el-tree-node__label) { font-size: 13px; }

:deep(.el-checkbox__label) { font-weight: normal; }

:deep(.el-tree-node__expand-icon) { margin-right: 6px; }
:deep(.el-tree-node__children) { margin-left: 16px; }
:deep(.el-tree-node__content:hover) { background-color: transparent; }

.drawer-footer {
  display: flex;
  justify-content: flex-end;
  gap: 12px;
  margin-top: auto;
  padding-top: 16px;
}

.w-full {
  width: 100%;
}
</style>
